package com.iflytek.autofly.setting.biz.base;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import com.iflytek.autofly.setting.R;
import com.iflytek.autofly.utils.FlyLog;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author yutian2 业务碎片基类
 */
public abstract class BaseFragment extends Fragment implements ICommand {

    private static final java.lang.String TAG = "BaseFragment";
    protected Bundle mExtraData;
    protected ProgressDialog mProgressDialog;
    ;
    private boolean mHasStarted = false;
    private LinearLayout mContainer;
    private com.iflytek.autofly.setting.biz.base.MyScrollView mScrollView;
    private String[] mCommands;
    private AtomicBoolean mCreated = new AtomicBoolean(false);

    private BlockingQueue<Runnable> mTodoList = new LinkedBlockingQueue<>();
    private HandlerThread mTodoHandlerThread;
    private Handler mTodoHandler;
    private int MSG_TODO_START = 0x1001;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.base_fragment, null);
        mContainer = (LinearLayout) view.findViewById(R.id.container);
        mScrollView = (com.iflytek.autofly.setting.biz.base.MyScrollView) view.findViewById(R.id.scroll);
        return view;
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mCreated.set(true);
        initPending();
        if (!mTodoList.isEmpty()) {
            mTodoHandler.sendEmptyMessage(MSG_TODO_START);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mCreated.set(false);
    }

    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
    }

    public void addUnit(int labelId, int subId,
                        OnExpandChangeListener labelListener,
                        OnExpandChangeListener subListener) {
        MyLinearLayout layout = new MyLinearLayout(getActivity(), labelId,
                subId);
        mContainer.addView(layout);
        layout.setExpandChangeListener(labelListener, subListener);
        MyOnClickListener l = new MyOnClickListener();
        l.setId(mContainer.getChildCount() - 1);
        layout.setLabelOnClickListener(l);
    }

    public void addUnit(int labelId, int subId) {
        addUnit(labelId, subId, null, null);
    }

    public void addUnit(int labelId) {
        addUnit(labelId, -1, null, null);
    }

    public void addHiddenUnit(int labelId, int subId,
                              OnExpandChangeListener labelListener,
                              OnExpandChangeListener subListener) {
        MyLinearLayout layout = new MyLinearLayout(getActivity(), labelId,
                subId);
        mContainer.addView(layout);
        layout.setExpandChangeListener(labelListener, subListener);
        MyOnClickListener l = new MyOnClickListener();
        l.setId(mContainer.getChildCount() - 1);
        layout.setLabelOnClickListener(l);
        layout.setVisibility(View.GONE);
    }

    public void addHiddenUnit(int labelId) {
        addHiddenUnit(labelId, -1, null, null);
    }

    public void addUnit(int labelId, OnExpandChangeListener labelListener) {
        addUnit(labelId, -1, labelListener, null);
    }

    public void setExpandable(int id, boolean expandable) {
        MyLinearLayout v = (MyLinearLayout) mContainer.getChildAt(id);
        if (v != null) {
            v.setExpandable(expandable);
        }
    }

    public void setVisibility(int id, int visibility) {
        MyLinearLayout v = (MyLinearLayout) mContainer.getChildAt(id);
        if (v != null) {
            v.setVisibility(visibility);
        }
    }

    public void collapseAll() {
        int len = mContainer.getChildCount();
        for (int i = 0; i < len; i++) {
            MyLinearLayout v = (MyLinearLayout) mContainer.getChildAt(i);
            if (v.isExpanded()) {
                v.collapse();
            }
        }
    }

    public void collapse(int id) {
        if (id >= mContainer.getChildCount()) {
            return;
        }
        MyLinearLayout v = (MyLinearLayout) mContainer.getChildAt(id);
        if (v.isExpanded()) {
            v.collapse();
        }
    }

    public void expand(int id) {
        int len = mContainer.getChildCount();
        if (id >= len) {
            return;
        }
        final MyLinearLayout v = (MyLinearLayout) mContainer.getChildAt(id);
        if (v.isExpandable() && !v.isExpanded()) {
            for (int i = 0; i < len; i++) {
                MyLinearLayout l = (MyLinearLayout) mContainer.getChildAt(i);
                if (i != id && l.isExpanded()) {
                    l.collapse();
                }
            }

            v.expand();
        }
        scrollTo(v);
    }

    public void scrollTo(final MyLinearLayout v) {
        // 效果不好，去除滚动效果
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                try {
//                    Thread.sleep(500);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                int[] scrollLocation = new int[2];
//                mScrollView.getLocationOnScreen(scrollLocation);
//                int[] location = new int[2];
//                v.getLocationOnScreen(location);
//                mScrollView.smoothScrollBy(location[0] - scrollLocation[0], location[1] - scrollLocation[1]);
//            }
//        }).start();
    }


    // //////////////////////加载提示框start////////////////////////////
    // 提示框属于UI进程,在界面UI发生变化(切换或�??�?)�?要在生命周期方法中dismiss
    // 该父类在 onPause onStop 中处�?
    public void showProgressDialog(CharSequence message) {
        if (mProgressDialog == null) {
            mProgressDialog = new ProgressDialog(getActivity());
            mProgressDialog.setIndeterminate(true);
        }
        if (!mProgressDialog.isShowing()) {
            mProgressDialog.setMessage(message);
            mProgressDialog.show();
        }
    }

    /**
     * @param
     * @Description: 提示框属于UI进程, 在界面UI发生变化(切换或�??�?)�?要在生命周期方法中dismiss，在 onPause
     * onStop 中处�?
     * @author 忧郁的西�? ★^_^+
     */
    public void dismissProgressDialog() {
        if (mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    }

    /**
     * 判断dialog是否显示
     *
     * @return boolean
     */
    public boolean isProgressDialogShowing() {
        if (mProgressDialog != null) {
            return mProgressDialog.isShowing();
        }
        return false;
    }

    public Bundle getExtraData() {
        return mExtraData;
    }

    public void setExtraData(Bundle extraData) {
        this.mExtraData = extraData;
    }

    // //////////////////////加载提示框start////////////////////////////

    @Override
    public void onDestroy() {
        super.onDestroy();
        dismissProgressDialog();
    }

    @Override
    public void onResume() {
        super.onResume();
        renew();
    }

    @Override
    public void onStart() {
        super.onStart();
        mHasStarted = true;
    }

    @Override
    public void onStop() {
        super.onStop();
        mHasStarted = false;
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden == false) {
            renew();
        }
    }

    public void callRenew() {
        if (mHasStarted) {
            renew();
        }
    }

    public void addFreezeView(View v) {
        mScrollView.addFreezeView(v);
    }

    public abstract void renew();

    public abstract void processCommandline(String cmd);

    public abstract String[] getCommands();

    @Override
    public void excute(final String cmdline) {
        if (mCreated.get()) {
            FlyLog.d(TAG, "cmd=" + cmdline);
            if (TextUtils.isEmpty(cmdline)) {
                return;
            }
            String[] cmds = new String[2];
            CommandHelper.getCommand(cmdline, cmds);
            if (TextUtils.isEmpty(cmds[0])) {
                return;
            }
            if (mCommands == null) {
                mCommands = getCommands();
            }
            int index;
            for (index = mCommands.length - 1; index >= 0; index--) {
                if (mCommands[index].equals(cmds[0])) {
                    break;
                }
            }
            if (index == -1) {
                return;
            }

            expand(index);
            if (!TextUtils.isEmpty(cmds[1])) {
                processCommandline(cmds[1]);
            }
        } else {
            pendingAction(new Runnable() {
                @Override
                public void run() {
                    excute(cmdline);
                }
            });
        }
    }

    private void pendingAction(Runnable runnable) {
        initPending();
        mTodoList.add(runnable);
    }

    private void initPending() {
        if (mTodoHandlerThread == null) {
            mTodoHandlerThread = new HandlerThread("todo");
            mTodoHandlerThread.start();
            mTodoHandler = new Handler(mTodoHandlerThread.getLooper(), new Handler.Callback() {
                @Override
                public boolean handleMessage(Message msg) {
                    if (msg.what == MSG_TODO_START) {
                        while (!mTodoList.isEmpty()) {
                            Runnable r = null;
                            try {
                                r = mTodoList.take();
                                r.run();
                            } catch (InterruptedException e) {
                                FlyLog.e(TAG, e);
                            }
                        }
                    }
                    return true;
                }
            });
        }
    }


    public interface OnExpandChangeListener {
        void onExpandChanged(boolean isExpanded);
    }

    private class MyOnClickListener implements OnClickListener {
        int id;

        public void setId(int id) {
            this.id = id;
        }

        @Override
        public void onClick(View view) {
            MyLinearLayout v = (MyLinearLayout) mContainer.getChildAt(id);
            if (!v.isExpanded()) {
                expand(id);
            } else {
                collapse(id);
            }
            scrollTo(v);
        }
    }
}
